package com.winit.openapi.isp.controller;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONObject;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.DeliveryAddressService;
import com.winit.erp.spi.bpartner.command.DeliveryAddressCommand;
import com.winit.erp.spi.bpartner.command.DeliveryAddressDeleteCommand;
import com.winit.erp.spi.bpartner.command.DeliveryAddressQueryCommand;
import com.winit.erp.spi.bpartner.command.DeliveryAddressUpdateCommand;
import com.winit.erp.spi.bpartner.vo.DeliveryAddress;
import com.winit.erp.spi.user.vo.User;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.isp.vo.CreatePickUpOrderAddr;
import com.winit.openapi.isp.vo.UpdatePickUpOrderAddr;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.ValidateUtil;

/**
 * 提货单地址信息维护
 * 
 * @author jiaohua.wu
 */
@Controller
@RequestMapping(value = "/pickupAddr")
public class PickUpOrderAddrController extends BaseController {

    @Resource
    private DeliveryAddressService deliveryAddressService;

    public void setDeliveryAddressService(DeliveryAddressService deliveryAddressService) {
        this.deliveryAddressService = deliveryAddressService;
    }

    // 查询提货单地址
    @RequestMapping(value = "/list")
    public String list(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        // 获取用户信息
        User user = (User) CommandContext.getContext().get(ApiConstant.API_USER);

        DeliveryAddressQueryCommand command = new DeliveryAddressQueryCommand();
        command.setClientId(user.getClientId());
        command.setbPartnerId(user.getBpartnerId());
        command.setOrgId(user.getOrgId());
        command.setCreatedby(user.getUserId());
        command.setUpdatedby(user.getUserId());
        command.setCtx(CommandContext.getContext());
        // 调用接口查询订单
        List<DeliveryAddress> addre = deliveryAddressService.queryAllDeliveryAddress(command);
        if (null != addre && addre.size() > 0) {
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            for (int i = 0; i < addre.size(); i++) {
                DeliveryAddress deliveryAddress = addre.get(i);
                Map<String, Object> map = new HashMap<String, Object>();

                map.put("countryName", nullToEmptyStr(deliveryAddress.getContactName()));

                map.put("countryID", deliveryAddress.getCountryId());
                map.put("provinceName", nullToEmptyStr(deliveryAddress.getRegionName()));
                map.put("provinceID", deliveryAddress.getRegionId());

                map.put("cityName", nullToEmptyStr(deliveryAddress.getCity()));
                map.put("cityID", deliveryAddress.getCityId());
                map.put("pickupAddress", nullToEmptyStr(deliveryAddress.getDeliveryAddress()));
                map.put("pickupAddressID", deliveryAddress.getDeliveryAddressId());
                map.put("email", nullToEmptyStr(deliveryAddress.getEmail()));
                map.put("contact", nullToEmptyStr(deliveryAddress.getContactName()));
                map.put("phoneNo", nullToEmptyStr(deliveryAddress.getPhone()));
                map.put("zipCode", nullToEmptyStr(deliveryAddress.getPostal()));

                list.add(map);
            }

            responseMsg.setData(list);
        }

        return SUCCESS;
    }

    /**
     * 查询提货单地址明细
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/query")
    public String query(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        JSONObject json = (JSONObject) requestMsg.getData();
        // 获取用户信息
        User user = (User) CommandContext.getContext().get(ApiConstant.API_USER);

        if (!isEixtValue(json, "pickupAddressID")) {
            throw new ApiException(ErrorCode.FIELD_NOT_NULL, "pickupAddressID");
        }
        String pickupAddressID = json.getString("pickupAddressID");

        if (!ValidateUtil.isLongNumber(pickupAddressID)) {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pickupAddressID");
        }

        DeliveryAddressQueryCommand command = new DeliveryAddressQueryCommand();
        command.setClientId(user.getClientId());
        command.setbPartnerId(user.getBpartnerId());
        command.setOrgId(user.getOrgId());
        command.setCreatedby(user.getUserId());
        command.setUpdatedby(user.getUserId());
        command.setDeliveryAddressId(Long.parseLong(pickupAddressID));
        command.setCtx(CommandContext.getContext());

        DeliveryAddress deliveryAddress = deliveryAddressService.queryDeliveryAddressById(command);
        if (null != deliveryAddress) {
            // 返回订单号
            Map<String, Object> data = new HashMap<String, Object>();

            data.put("pickupAddressID", pickupAddressID);
            data.put("pickupAddress", nullToEmptyStr(deliveryAddress.getDeliveryAddress()));
            data.put("countryName", nullToEmptyStr(deliveryAddress.getCountryName()));
            data.put("countryID", deliveryAddress.getCountryId());
            data.put("provinceName", nullToEmptyStr(deliveryAddress.getRegionName()));
            data.put("provinceID", deliveryAddress.getRegionId());
            data.put("cityName", nullToEmptyStr(deliveryAddress.getCity()));
            data.put("cityID", deliveryAddress.getCityId());
            data.put("email", nullToEmptyStr(deliveryAddress.getEmail()));
            data.put("contact", nullToEmptyStr(deliveryAddress.getContactName()));
            data.put("phoneNo", nullToEmptyStr(deliveryAddress.getPhone()));
            data.put("zipCode", nullToEmptyStr(deliveryAddress.getPostal()));

            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    // 创建提货单地址
    @RequestMapping(value = "/create")
    public String create(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 解析参数
        JSONObject json = (JSONObject) requestMsg.getData();
        CreatePickUpOrderAddr pickOrderAddress = (CreatePickUpOrderAddr) toBean("com.winit.openapi.isp.vo.CreatePickUpOrderAddr",
            json);
        // 获取用户信息
        User user = (User) CommandContext.getContext().get(ApiConstant.API_USER);

        // 校验参数
        ValidateUtil.validateWithExp(pickOrderAddress);

        // 组装spi对象
        DeliveryAddressCommand command = setDeliveryAddressCommandCreate(pickOrderAddress, user);
        command.setCtx(CommandContext.getContext());
        // 调用接口创建订单
        Long pickOrderAddressId = deliveryAddressService.insertDeliveryAddressById(command);

        // 返回订单号
        Map<String, Long> data = new HashMap<String, Long>();

        data.put("pickupAddressID", pickOrderAddressId);
        responseMsg.setData(data);

        return SUCCESS;
    }

    /**
     * 组装创建提货单地址实体对象
     * 
     * @param pickOrderAddress
     * @param user
     * @return
     */
    private DeliveryAddressCommand setDeliveryAddressCommandCreate(CreatePickUpOrderAddr pickOrderAddress, User user) {
        DeliveryAddressCommand command = new DeliveryAddressCommand();
        BeanUtils.copyProperties(pickOrderAddress, command);

        command.setClientId(user.getClientId());
        command.setbPartnerId(user.getBpartnerId());
        command.setOrgId(user.getOrgId());
        command.setCreatedby(user.getUserId());
        command.setUpdatedby(user.getUserId());

        command.setCountryId(pickOrderAddress.getCountryID());
        command.setRegionId(pickOrderAddress.getProvinceID());
        command.setCityId(pickOrderAddress.getCityID());

        command.setDeliveryAddress(pickOrderAddress.getPickupAddress());

        command.setContactName(pickOrderAddress.getContact());
        command.setPhone(pickOrderAddress.getPhoneNo());
        command.setPostal(pickOrderAddress.getZipCode());

        return command;
    }

    /**
     * 修改提货单地址
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/update")
    public String update(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 解析参数
        JSONObject json = (JSONObject) requestMsg.getData();
        UpdatePickUpOrderAddr pickOrderAddress = (UpdatePickUpOrderAddr) toBean("com.winit.openapi.isp.vo.UpdatePickUpOrderAddr",
            json);

        // 获取用户信息
        User user = (User) CommandContext.getContext().get(ApiConstant.API_USER);

        // 校验参数
        ValidateUtil.validateWithExp(pickOrderAddress);

        // 组装实体对象 `
        DeliveryAddressUpdateCommand command = setDeliveryAddressUpdateCommand(pickOrderAddress, user);
        command.setCtx(CommandContext.getContext());
        // 调用接口修改订单
        deliveryAddressService.updateDeliveryAddressById(command);

        return SUCCESS;
    }

    // 修改实体对象赋值
    private DeliveryAddressUpdateCommand setDeliveryAddressUpdateCommand(UpdatePickUpOrderAddr pickOrderAddress,
                                                                         User user) {
        DeliveryAddressUpdateCommand command = new DeliveryAddressUpdateCommand();
        BeanUtils.copyProperties(pickOrderAddress, command);

        command.setClientId(user.getClientId());
        command.setbPartnerId(user.getBpartnerId());
        command.setOrgId(user.getOrgId());
        command.setCreatedby(user.getUserId());
        command.setUpdatedby(user.getUserId());

        command.setDeliveryAddressId(pickOrderAddress.getPickupAddressID());
        command.setCountryId(pickOrderAddress.getCountryID());
        command.setRegionId(pickOrderAddress.getProvinceID());
        command.setCityId(pickOrderAddress.getCityID());
        command.setDeliveryAddress(pickOrderAddress.getPickupAddress());
        command.setEmail(pickOrderAddress.getEmail());
        command.setContactName(pickOrderAddress.getContact());
        command.setPhone(pickOrderAddress.getPhoneNo());
        command.setPostal(pickOrderAddress.getZipCode());

        return command;
    }

    // 删除提货单地址
    @RequestMapping(value = "/delete")
    public String delete(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 解析参数
        JSONObject json = (JSONObject) requestMsg.getData();
        // 获取用户信息
        User user = (User) CommandContext.getContext().get(ApiConstant.API_USER);

        if (!isEixtValue(json, "pickupAddressID")) {
            throw new ApiException(ErrorCode.FIELD_NOT_NULL, "pickupAddressID");
        }
        String pickupAddressID = json.getString("pickupAddressID");

        if (pickupAddressID.length() > 11) {
            throw new ApiException(ErrorCode.FIELD_LENGTH_TO_LONG, "pickupAddressID", 11, 0);
        }

        if (!ValidateUtil.isLongNumber(pickupAddressID)) {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pickupAddressID");
        }

        DeliveryAddressDeleteCommand command = new DeliveryAddressDeleteCommand();
        command.setbPartnerId(user.getBpartnerId());

        command.setDeliveryAddressId(Long.parseLong(pickupAddressID));
        command.setCtx(CommandContext.getContext());
        // 调用接口删除提货单地址
        boolean result = deliveryAddressService.deleteDeliveryAddressById(command);
        if (!result) {
            throw new ApiException(ErrorCode.FIELD_DELETE_FAILURE);
        }
        return SUCCESS;
    }

    // 判断非必填字段是否有值
    public boolean isEixtValue(JSONObject jsonObject, String key) {
        if (jsonObject.containsKey(key)) {
        	 return !"".equals(jsonObject.getString(key).trim());
        }
        return false;
    }

    /**
     * json转对象
     * 
     * @param className类目
     * @param jsonObject
     * @return
     */
    public Object toBean(String className, JSONObject jsonObject) {
        Object object = null;
        Class<?> type;
        try {
            type = Class.forName(className);
            object = (Object) type.newInstance();
            Field[] field = type.getDeclaredFields();
            for (int i = 0; i < field.length; i++) {
                String fieldName = field[i].getName();
                String methodName = "set" + (fieldName.charAt(0) + "").toUpperCase()
                                    + fieldName.substring(1, fieldName.length());
                if (isEixtValue(jsonObject, fieldName)) {
                    if (field[i].getType().equals(Long.class)) {
                        if (!ValidateUtil.isLongNumber(jsonObject.getString(fieldName))) {
                            throw new ClassCastException(field[i].getName());
                        }
                        Method method = type.getMethod(methodName, new Class[] { Long.class });
                        method.invoke(object, jsonObject.getLong(fieldName));
                    }
                    if (field[i].getType().equals(Integer.class)) {
                        if (!ValidateUtil.isIntNumber(jsonObject.getString(fieldName))) {
                            throw new ClassCastException(field[i].getName());
                        }
                        Method method = type.getMethod(methodName, new Class[] { Integer.class });
                        method.invoke(object, jsonObject.getInteger(fieldName));
                    } else if (field[i].getType().equals(String.class)) {
                        Method method = type.getMethod(methodName, new Class[] { String.class });
                        method.invoke(object, jsonObject.getString(fieldName));
                    } else if (field[i].getType().equals(Date.class)) {
                        if (!ValidateUtil.isDateFormat(jsonObject.getString(fieldName),
                            new SimpleDateFormat(ValidateUtil.DATE_PATTERN_BASE))) {
                            throw new ClassCastException(field[i].getName());
                        }
                        Method method = type.getMethod(methodName, new Class[] { Date.class });
                        method.invoke(object, jsonObject.getDate(fieldName));
                    } else if (field[i].getType().equals(Float.class)) {
                        if (!ValidateUtil.isFloat(jsonObject.getString(fieldName))) {
                            throw new ClassCastException(field[i].getName());
                        }
                        Method method = type.getMethod(methodName, new Class[] { Date.class });
                        method.invoke(object, jsonObject.getFloat(fieldName));
                    }
                }

            }
        } catch (ClassCastException e) {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return object;
    }

    public String nullToEmptyStr(String str) {
        return null == str ? "" : str;
    }

}
